package org.apache.dolphinscheduler.service.inputparam;

import com.alibaba.fastjson.JSONObject;
import org.apache.dolphinscheduler.common.thread.ThreadPoolExecutors;
import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.dao.mapper.InputParamMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessInstanceMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessTaskRelationMapper;
import org.apache.dolphinscheduler.dao.mapper.TaskInstanceMapper;
import org.apache.dolphinscheduler.service.process.ProcessService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@Service
public class InputParamService {

    private static final Logger logger = LoggerFactory.getLogger(InputParamService.class);

    @Autowired
    InputParamMapper inputParamMapper;

    @Autowired
    ProcessTaskRelationMapper processTaskRelationMapper;

    @Autowired
    TaskInstanceMapper taskInstanceMapper;

    @Autowired
    ProcessInstanceMapper processInstanceMapper;

    @Autowired
    ProcessService processService;


    public void insert(InputParam inputParam) {

        inputParamMapper.insert(inputParam);

    }

    /**
     * insert input param
     */
    public void insertInputParam(TaskInstance taskInstance) {


        inputParamMapper.deleteByNodeId(taskInstance.getId());

        ProcessInstance processInstance = processService.findProcessInstanceDetailById(taskInstance.getProcessInstanceId());

        ProcessDefinition processDefinition = processService.findProcessDefinition(processInstance.getProcessDefinitionCode(),
                processInstance.getProcessDefinitionVersion());


        List<ProcessTaskRelation> processTaskRelations = processService.findRelationByCodeAndTaskCode(processDefinition.getCode(), processDefinition.getVersion(), taskInstance.getTaskCode());
//        List<ProcessTaskRelation> processTaskRelations = processTaskRelationMapper.queryByPostTaskCode(taskInstance.getTaskCode());

        for (int i = 0; i < processTaskRelations.size(); i++) {

            if (processTaskRelations.get(i).getPreTaskCode() == 0) {
                insertInputParam(taskInstance, null);
            } else {
                ProcessTaskRelation processTaskRelation = processTaskRelations.get(i);
                insertInputParam(taskInstance, processTaskRelation);
            }
        }
    }

    /**
     *
     */
    public void delByProcessInstanceId(int processInstanceId) {
        inputParamMapper.delByProcessInstanceId(processInstanceId);
    }

    public void delByProcessDefinitionId(int processDefinitionId) {
        inputParamMapper.delByProcessDefinitionId(processDefinitionId);
    }

    public void insertInputParam(TaskInstance taskInstance, ProcessTaskRelation processTaskRelation) {
        String param = JSONObject.parseObject(taskInstance.getInputParam()).getJSONObject("nodeParam").toJSONString();
        InputParam inputParam = new InputParam();
        inputParam.setInputParam(param);
        inputParam.setNodeId(taskInstance.getId());
        inputParam.setTag(taskInstance.getName());
        inputParam.setCreateTime(new Date());
        inputParam.setSecondType(taskInstance.getSecondType());
        inputParam.setProcessInstanceId(taskInstance.getProcessInstanceId());

        if (null != processTaskRelation) {
            //没有版本信息，只能这样确定唯一
            List<TaskInstance> taskInstanceList = taskInstanceMapper.queryByInstanceCode(processTaskRelation.getPreTaskCode());
            for (int i = 0; i < taskInstanceList.size(); i++) {
                if (taskInstance.getLastTasks().containsKey(taskInstanceList.get(i).getId())) {
                    inputParam.setLastNodeId(taskInstanceList.get(i).getId());
                    inputParam.setLastTag(taskInstanceList.get(i).getSecondType());
                }
            }
            Long postTaskPort = processTaskRelation.getPostTaskPortCode() % 10;
            Long preTaskPort = processTaskRelation.getPreTaskPortCode() % 10;
            inputParam.setNodeInputPoint(postTaskPort.intValue());
            inputParam.setLastNodeOutputPoint(preTaskPort.intValue());
        }
        inputParamMapper.insert(inputParam);
    }
}
